package com.skyworth.ui.api;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;

import com.skyworth.util.Util;

import java.util.ArrayList;
import java.util.List;

/**
 * @author : lgx
 * @ClassName SkyPlayingView
 * @Description : 用于表示当前正在活动的View，View会做线条动画，可以停止，播放，并设置条数，宽高等参数
 * @date : 2018/6/20 16:10
 */
public class SkyPlayingView extends View {

    private int mWidth; //View宽
    private int mHeight; //View高
    private int mColor = 0xffffffff; //线条颜色
    private int mLineCont = 4; //线条数目，默认是4条
    private int mLineWidth = 0; //线条宽度
    private int mLineMagin = 0;
    private long mDuration = 1200; //各条动画时长
    private boolean isAnimRunning = false; //动画状态

    private List<ValueAnimator> mAnims = new ArrayList<ValueAnimator>();
    private List<MyAnimUpdateListener> mAnimUpdateListeners = new ArrayList<MyAnimUpdateListener>();
    private List<Float> mStartX = new ArrayList<Float>();
    private List<Float> mEndY = new ArrayList<Float>();

    private Float[] mfirstLinePoint = new Float[]{0.2f, 0.7f, 0.2f, 0.7f, 0.1f};
    private Float[] mSecondLinePoint = new Float[]{0.5f, 0f, 0.5f, 0f, 0.5f};
    private Float[] mThirdLinePoint = new Float[]{0f, 0.5f, 0f, 0.5f, 0f};
    private Float[] mLastLinePoint = new Float[]{0.7f, 0.2f, 0.7f, 0.2f, 0.7f};

    private Paint mPaint; //画笔

    public SkyPlayingView(Context context) {
        super(context);
        initDefaultValue();
    }

    private void initDefaultValue() {
        mLineCont = 4;
        mWidth = Util.Div(24);
        mHeight = Util.Div(24);
        mLineWidth = mWidth / (mLineCont * 2);
        mLineMagin = mWidth / ((mLineCont - 1) * 2);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        mPaint.setColor(mColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeCap(Paint.Cap.BUTT);
        mPaint.setStrokeWidth(mLineWidth);
        initAnim();
    }

    private void initAnim() {
        if(mAnims != null && mAnims.size() > 0) {
            for (int i = 0; i < mAnims.size(); i++) {
                mAnims.get(i).cancel();
            }
            mAnims.clear();
        }
        for (int i = 0; i < mLineCont; i++) {
            ValueAnimator anim = null;
            if(i == 0) {
                anim = ValueAnimator.ofFloat(mHeight *mfirstLinePoint[0], mHeight *mfirstLinePoint[1]
                        , mHeight *mfirstLinePoint[2], mHeight *mfirstLinePoint[3]);
            }else if(i == (mLineCont - 1)) {
                anim = ValueAnimator.ofFloat(mHeight *mLastLinePoint[0], mHeight *mLastLinePoint[1]
                        , mHeight *mLastLinePoint[2], mHeight *mLastLinePoint[3]);
            } else if(i % 2 == 0) {
                anim = ValueAnimator.ofFloat(mHeight *mThirdLinePoint[0], mHeight *mThirdLinePoint[1]
                        , mHeight *mThirdLinePoint[2], mHeight *mThirdLinePoint[3]);
            }else {
                anim = ValueAnimator.ofFloat(mHeight *mSecondLinePoint[0], mHeight *mSecondLinePoint[1]
                        , mHeight *mSecondLinePoint[2], mHeight *mSecondLinePoint[3]);
            }
            MyAnimUpdateListener listener = new MyAnimUpdateListener(i);
            anim.addUpdateListener(listener);
            anim.setDuration(mDuration);
            anim.setRepeatCount(ValueAnimator.INFINITE);
            anim.setRepeatMode(ValueAnimator.REVERSE);
//            anim.setStartDelay(400);
            anim.setInterpolator(new LinearInterpolator());
            mAnims.add(anim);
            mAnimUpdateListeners.add(listener);
        }
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        ViewGroup.LayoutParams params = this.getLayoutParams();
        if(params != null) {
            if(params.width != 0) {
                mWidth = params.width;
            } else {
                mWidth = w;
            }

            if(params.height != 0) {
                mHeight = params.height;
            } else {
                mHeight = h;
            }
        }
        mLineWidth = mWidth / (mLineCont * 2);
        mLineMagin = mWidth / ((mLineCont - 1) * 2);
        if(mEndY != null) {
            mEndY.clear();
        }
        if(mStartX != null) {
            mStartX.clear();
        }
        for (int i = 0; i < mLineCont; i++) {
            if(i == 0) {
                mEndY.add(mHeight *mfirstLinePoint[0]);
            }else if(i == (mLineCont - 1)) {
                mEndY.add(mHeight *mLastLinePoint[0]);
            } else if(i % 2 == 0) {
                mEndY.add(mHeight *mThirdLinePoint[0]);
            }else {
                mEndY.add(mHeight *mSecondLinePoint[0]);
            }
            mStartX.add((float) (i * mLineWidth + i * mLineMagin + mLineWidth / 2));
        }
        initAnim();
        mPaint.setStrokeWidth(mLineWidth);
        invalidate();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        isAnimRunning = false;
        for (int i = 0; i < mAnims.size(); i++) {
            mAnims.get(i).cancel();
            mAnims.get(i).removeUpdateListener(mAnimUpdateListeners.get(i));
        }
        mAnimUpdateListeners.clear();
        mAnims.clear();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        initAnim();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawLines(canvas);
    }

    private void drawLines(Canvas canvas) {
        for (int i = 0; i < mLineCont; i++) {
            canvas.drawLine(mStartX.get(i), mHeight, mStartX.get(i), mEndY.get(i), mPaint);
        }
    }

    public boolean isAnimRunning() {
        return isAnimRunning;
    }

    public void startAnim() {
        isAnimRunning = true;
        Log.v("lgx", "startAnim !!!!!" + mAnims.size());
        this.post(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < mAnims.size(); i++) {
                    mAnims.get(i).cancel();
                    mAnims.get(i).start();
                    Log.v("lgx", "startAnim isRunning--->" + mAnims.get(i).isRunning());
                }
            }
        });
    }

    public void stopAnim() {
        isAnimRunning = false;
        for (int i = 0; i < mAnims.size(); i++) {
            mAnims.get(i).cancel();
            Log.v("lgx", "stopAnim  isRunning--->" + mAnims.get(i).isRunning());
        }

        if(mEndY != null) {
            mEndY.clear();
        }
        if(mStartX != null) {
            mStartX.clear();
        }
        for (int i = 0; i < mLineCont; i++) {
            if(i == 0) {
                mEndY.add(mHeight *mfirstLinePoint[0]);
            }else if(i == (mLineCont - 1)) {
                mEndY.add(mHeight *mLastLinePoint[0]);
            } else if(i % 2 == 0) {
                mEndY.add(mHeight *mThirdLinePoint[0]);
            }else {
                mEndY.add(mHeight *mSecondLinePoint[0]);
            }
            mStartX.add((float) (i * mLineWidth + i * mLineMagin + mLineWidth / 2));
        }
        invalidate();
    }

    public void destroy() {
        if(mAnims == null)
            return;
        for (int i = 0; i < mAnims.size(); i++) {
            mAnims.get(i).removeAllUpdateListeners();
        }
    }

    public void setmLineCont(int mLineCont) {
        this.mLineCont = mLineCont;
        mLineWidth = mWidth / mLineCont;
        mLineMagin = mWidth / (mLineCont - 1);
        mPaint.setStrokeWidth(mLineWidth);
        initAnim();
        invalidate();
    }

    public int getmWidth() {
        return mWidth;
    }

    public int getmHeight() {
        return mHeight;
    }

    public int getmColor() {
        return mColor;
    }

    public void setmColor(int mColor) {
        this.mColor = mColor;
        mPaint.setColor(mColor);
        invalidate();
    }

    public long getmDuration() {
        return mDuration;
    }

    public void setmDuration(long mDuration) {
        this.mDuration = mDuration;
    }

    private class MyAnimUpdateListener implements ValueAnimator.AnimatorUpdateListener {

        private int index;

        public MyAnimUpdateListener(int index) {
            this.index = index;
        }

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            if(mEndY.size() > 0){
                mEndY.set(index, (Float) animation.getAnimatedValue());
                if(index == 0) {
                    SkyPlayingView.this.invalidate();
                }
            }
        }
    }

}
